import Vue from "vue";
import axios from "axios";
import stroe from "@/store";
import router from "@/router";
import { MessageBox, Message } from "element-ui";
import store from "../store";

Vue.component(MessageBox.name, MessageBox);

const instance = axios.create({
  baseURL: "/api",
  headers: {
    "content-type": "application/json;charset=UTF-8",
  },
  timeout: 8000,
  withCredentials: true,
});
let axiosSourceList = [];

// 添加请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 在发送请求之前做某些
    // 判断当前请求是否可以取消
    if (!config.noCancel) {
      let axiosSource = axios.CancelToken.source();
      config.cancelToken = axiosSource.token;
      axiosSourceList.push(axiosSource);
    }
    // config.headers.Token = sessionStorage.getItem("TOKEN");
    config.headers.Token = `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NjI1MTk1NzcsInVzZXJuYW1lIjoiYWRtaW4ifQ.YdVYgQPVVZblMQ2SeokFT1anTIqgjIkz_jmEThdnUIc`;
    if (config.loadingName) {
      stroe.dispatch(`setLoadingList`, {
        key: config.loadingName,
        value: true,
      });
    }
    return config;
  },
  (error) => {
    // 请求错误时做某些事
    return Promise.reject(error);
  }
);

// 添加响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 设置全局的接口请求状态
    if (response.config.loadingName) {
      stroe.dispatch(`setLoadingList`, {
        key: response.config.loadingName,
        value: false,
      });
    }
    // 返回数据处理
    // 其中code 200：操作正常，页面无提示
    // code 20000:操作成功 提示message
    // Code 20001:操作失败 提示message
    // 401：无权限，500异常报错。
    if (response.data.code === "200") {
      return response.data;
    } else if (response.data.code === "20000") {
      Message.success({
        message: response.data.message,
        center: true,
      });
      return response.data;
    } else if (response.data.code === "20001") {
      Message.error({
        message: response.data.message,
        center: true,
      });
      return Promise.reject(response);
    } else if (response.data.code === "401") {
      Message.error({
        message: response.data.message,
        center: true,
      });
      sessionStorage.clear();
      router.replace(`/login`);
      setTimeout(() => {
        store.dispatch(`setRoleMenuData`, {
          menuTree: [],
          roleMenuData: [],
        });
      }, 1000);
      axiosSourceList.forEach((item) => {
        item.cancel();
      });
      axiosSourceList = [];
      return Promise.reject(response);
    } else {
      Message.error({
        message: response.data.message,
        center: true,
      });
      return Promise.reject(response);
    }
  },
  (error) => {
    // 响应错误时做某些事
    if (error?.config?.loadingName) {
      stroe.dispatch(`setLoadingList`, {
        key: error.config.loadingName,
        value: false,
      });
    }
    // 接口超时处理
    if (error?.message.includes("timeout")) {
      Message.error({
        message: "接口请求超时，请重试",
        center: true,
      });
    }
    // 网络错误处理
    if (error?.message === "Network Error") {
      Message.error({
        message: "网络错误，请查看当前网络状态",
        center: true,
      });
    }
    if (error?.response?.status) {
      switch (error.response.status) {
        // 401: 未登录
        // 未登录则跳转登录页面，并携带当前页面的路径
        // 在登录成功后返回当前页面，这一步需要在登录页操作。
        case 401:
          Message.error({
            message: `未登录或请重新登录`,
            center: true,
          });
          break;
        // 403 token过期
        // 登录过期对用户进行提示
        // 清除本地token和清空vuex中token对象
        // 跳转登录页面
        case 403:
          break;
        // 404请求不存在
        case 404:
          Message.error({
            message: `请求地址错误`,
            center: true,
          });
          break;
        case 500:
          Message.error({
            message: `服务器错误`,
            center: true,
          });
          break;
        // 其他错误，直接抛出错误提示
        default:
          Message.error({
            message: `接口请求错误`,
            center: true,
          });
      }
    }
    return Promise.reject(error);
  }
);

export default instance;
